use crate::{
    handler::Endpoint, handler::MiddlewareEndpoint, http, middleware::Middleware, request::Request,
    router::Router, utils::async_trait,
};
use std::sync::Arc;

pub struct Route<'a> {
    router: &'a mut Router,
    path: String,
    middleware: Vec<Arc<dyn Middleware>>,
}

impl<'a> Route<'a> {
    ///通过给定的路径生成route
    pub fn at<'b>(&'b mut self, path: &str) -> Route<'b> {
        let mut p = self.path.clone();

        if !p.ends_with('/') && !path.starts_with('/') {
            p.push('/');
        }

        if path != "/" {
            p.push_str(path);
        }

        Route {
            router: &mut self.router,
            path: p,
            middleware: self.middleware.clone(),
        }
    }

    pub(crate) fn new(router: &'a mut Router, path: String) -> Route<'a> {
        Route {
            router,
            path,
            middleware: Vec::new(),
        }
    }

    pub fn method(&mut self, method: http::Method, ep: impl Endpoint) -> &mut Self {
        let ep: Box<dyn Endpoint> = if self.middleware.is_empty() {
            Box::new(ep)
        } else {
            Box::new(MiddlewareEndpoint::wrap_with_middleware(
                ep,
                &self.middleware,
            ))
        };
        self.router.add(&self.path, method, ep);

        self
    }
}
